package main

import "fmt"

func main() {
	//func（函数）本质是一个变量
	fmt.Printf("函数的类型:%T\n", main) //函数的类型:func()
	fmt.Println("函数的地址:", main)    //函数的地址: 0x108b900

	//定义一个函数
	var myFunc func(int, int) int
	myFunc = add
	fmt.Printf("两数相加为:%d\n", myFunc(1, 2)) //两数相加为:3

	//匿名函数
	result := func(a, b int) int {
		return myFunc(a, b)
	}(2, 3)
	fmt.Printf("两数相加为:%d\n", result) //两数相加为:5

	//高阶函数
	fmt.Printf("两数相加为:%d\n", operation(123, 456, add)) //两数相加为:579
	fmt.Printf("两数相减为:%d\n", operation(123, 456, sub)) //两数相减为:-333

	/*
		闭包：将函数包括函数的上文环境封装，上下文环境会被保存而非副本

		两数相加为:579
		两数相减为:-533
		两数相加为:579
		两数相减为:-535
	*/
	myClosure := closure()
	myClosure(123, 456)
	myClosure(123, 456)
}

func add(a, b int) int {
	return a + b
}

func sub(a, b int) int {
	return a - b
}

func operation(a, b int, fun func(int, int) int) int {
	return fun(a, b)
}

func closure() func(int, int) {
	c := 100
	return func(a, b int) {
		a -= c
		b += c
		c++
		fmt.Printf("两数相加为:%d\n", operation(a, b, add))
		fmt.Printf("两数相减为:%d\n", operation(a, b, sub))
	}
}
